package com.bzframework.pro.authorize.context;

import com.bzframework.pro.authorize.token.parser.ParsedToken;
import com.bzframework.pro.authorize.token.UserToken;
import com.bzframework.pro.authorize.token.manager.UserTokenManager;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.simple.SimpleAuthentication;
import org.hswebframework.web.authorization.simple.SimpleUser;
import org.springframework.http.server.reactive.ServerHttpRequest;
import reactor.core.publisher.Mono;

/**
 * @Author bingzhong
 * @Date 2024/11/23 22:27
 * @Description
 */
public final class ReactiveUserTokenContextHolder {

    private static UserTokenManager userTokenManager;

    public static final Class<ServerHttpRequest> REQUEST_CONTEXT_KEY = ServerHttpRequest.class;

    public static void setManager(UserTokenManager manager) {
        userTokenManager = manager;
    }

    public static Mono<UserToken> get() {
        return Mono.deferContextual(ctx -> ctx
                .<ParsedToken>getOrEmpty(ParsedToken.class)
                .map(t -> userTokenManager.getUserToken(t.getToken()))
                .orElse(Mono.empty()));
    }

    public static Mono<UserToken> get(String token) {
        return userTokenManager.getUserToken(token);
    }

    /**
     * 获取request对象
     * @return
     */
    public static Mono<ServerHttpRequest> getRequest() {
        return Mono.deferContextual(ctx -> Mono.just(ctx.get(REQUEST_CONTEXT_KEY)));
    }

    /**
     * 获取当前用户信息 适配 hsweb
     * @return
     */
    public static Mono<Authentication> currentReactive() {
        return get().flatMap(ReactiveUserTokenContextHolder::fromUserToken2Authentication);
    }

    private static Mono<SimpleAuthentication> fromUserToken2Authentication(UserToken userToken) {
        SimpleAuthentication simpleAuthentication = new SimpleAuthentication();
        SimpleUser simpleUser = new SimpleUser();
        simpleUser.setId(userToken.getUserId());
        simpleAuthentication.setUser(simpleUser);
        return Mono.just(simpleAuthentication);
    }

}
